/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.yonsei.iwb.sdt.refinement;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.vocabulary.RDF;
import edu.yonsei.iwb.sdt.datastructure.TargetInstance;
import java.util.ArrayList;
import java.util.Vector;

/**
 *
 * @author JDK
 */
public class ConceptConstructorRefinement extends Refinement{    
    private String name = new String();
    private String corename = new String();
    private boolean multi = false;
    private String conditionr;
    private ArrayList<String> subset;
            
    public ConceptConstructorRefinement(ConceptConstructorRefinement oldccr){
        this.name = oldccr.getName();
        this.corename = oldccr.getCoreName();
        this.conditionr = oldccr.getConditionResource();
        this.multi = oldccr.isMulti();
        super.refinementType = RefinementType.CONCEPTCONSTRUCTOR;
    }    
    
    public ConceptConstructorRefinement(String prefix, String r){
        this.name = prefix +r;
        this.corename = prefix +r;
        this.conditionr = r;
        this.cc = new ConstraintConstructor(r);
        super.refinementType = RefinementType.CONCEPTCONSTRUCTOR;        
    }
    
    public ConceptConstructorRefinement(String prefix, String r, int reftype){
        this.name = prefix +r;
        this.corename = prefix +r;
        this.conditionr = r;
        this.cc = new ConstraintConstructor(r);
        super.refinementType = reftype;        
    }
    
    
    /**
     * 다수의 디스조인트 리소스에 포함되지 않은 클래스 들의 합집합 리파인먼트
     * @param subset 
     */
    public ConceptConstructorRefinement(ArrayList<String> subset){
        String cons = new String();
        this.multi = true;        
        for (int i = 0; i < subset.size(); i++) {
            String r = subset.get(i);
            if(i!=subset.size()-1){                
                cons += r + DLConstructors.DISJUNCTION;
            }else{
                cons += r;
            }
        }        
        this.name = DLConstructors.NEGATION+"("+ cons +")";
        this.corename = DLConstructors.NEGATION+"("+ cons +")";
        this.cc = new ConstraintConstructor(cons);
        this.subset = subset;
        super.refinementType = RefinementType.CONCEPTCONSTRUCTOR;
    }

    @Override
    public void generateRefinementName() {
        super.refinement_name = this.name;
    }
    
    @Override
    public Refinement generateUpdatedRefinement(Vector<TargetInstance> instanceSet){
        Refinement ref = new ConceptConstructorRefinement(this);
        ref.setBranchingType(this.branching_type);
        ref.setConstraintConstructor(this.cc);
        
        Vector<TargetInstance> oldinsSet = this.getInstanceSet();        
        for (int i = 0; i < instanceSet.size(); i++) {
            TargetInstance ti = instanceSet.get(i);
            if(oldinsSet.contains(ti)){
                ref.setInstanceSet(ti);
            }
        }
//        private boolean refinement_type = true;
//        protected String refinement_name;
//        private Vector<Resource> instanceSet;
        return ref;
    }

    public String getName() {
        return name;
    }

    public ArrayList<String> getSubset() {
        return subset;
    }    

    public String getConditionResource() {
        return conditionr;
    }
    
    public boolean isMulti(){
        return this.multi;
    }
    
    @Override
    public ExpandingHistory getExpandingHistory() {
        return null;
    }
    
    @Override
    public String getCoreName() {
        return this.corename;
    }

    
    @Override
    public Vector<Resource> getConstraintMatcherInstance(Model model) {
        Vector<Resource> matchedSet = new Vector();
        
        ResIterator res = model.listResourcesWithProperty(RDF.type, this.conditionr);
        while(res.hasNext()){
            matchedSet.add(res.nextResource());
        }                
//        throw new UnsupportedOperationException("Not supported yet.");
        return matchedSet;
    }
}
